package org.jeecg.modules.settlement.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.jeecg.common.modules.doctor.entity.Doctor;
import org.jeecg.common.modules.doctor.service.IDoctorAccountService;
import org.jeecg.common.modules.doctor.service.IDoctorService;
import org.jeecg.common.modules.order.entity.OrderInfo;
import org.jeecg.common.modules.order.service.IOrderInfoLogService;
import org.jeecg.common.modules.order.service.IOrderInfoService;
import org.jeecg.common.modules.settlement.entity.Settlement;
import org.jeecg.common.modules.settlement.service.ISettlementDetailService;
import org.jeecg.common.modules.settlement.service.ISettlementService;
import org.jeecg.common.modules.sys.service.ISysAccountService;
import org.jeecg.common.util.AmountUtils;
import org.jeecg.common.util.DySmsEnum;
import org.jeecg.common.util.DySmsHelper;
import org.jeecg.common.util.enums.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author guoyh
 * @ClassName AdminSettlementService
 * @Description
 * @since 2020/9/5 13:06
 **/
@Service
@Slf4j
public class AdminSettlementService {

    @Resource
    private IOrderInfoService orderInfoService;
    @Resource
    private ISettlementService settlementService;
    @Resource
    private IDoctorService doctorService;
    @Resource
    private ISettlementDetailService settlementDetailService;
    @Resource
    private IDoctorAccountService doctorAccountService;
    @Resource
    private ISysAccountService sysAccountService;
    @Resource
    private IOrderInfoLogService orderInfoLogService;


    /**
     * 结算
     * @param id
     * @param loginUser
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public Pair<Boolean,String> settlement(Long id,String loginUser){
        Settlement exist = settlementService.getById(id);
        if (Objects.isNull(exist)){
            return Pair.of(false,"未获取到问诊单信息");
        }
        if (!Objects.equals(exist.getStatus(), SettlementStatusEnum.WAIT.getCode())){
            return Pair.of(false,"问诊单状态已变更，请刷新页面后重试");
        }
        OrderInfo order = orderInfoService.getById(exist.getRelationId());
        if (Objects.isNull(order)){
            return Pair.of(false,"未获取到订单信息");
        }
        Doctor doctor = doctorService.getById(order.getDoctorId());
        if (Objects.isNull(doctor) || Objects.isNull(doctor.getShare())){
            return Pair.of(false,"未获取到医生信息或医生未设置分成比例");
        }
        BigDecimal ratio = AmountUtils.fenToYuan(doctor.getShare());
        BigDecimal amount  = order.getAmount();
        BigDecimal doctorAmount = amount.multiply(ratio);
        BigDecimal platformAmount = amount.subtract(doctorAmount);

        //结算详情新增处理
        settlementDetailService.initSettlementDetail(exist, SettlementDetailTypeEnum.DOCTOR,doctor.getId(),doctorAmount,ratio,loginUser);

        //医生账户变动处理
        doctorAccountService.changeBalance(order.getDoctorId(),doctorAmount, AccountFlowTypeEnum.INCOME,exist.getId().toString());

        //系统账户操作记录处理
        sysAccountService.changeSysBalance(SysAccountTypeEnum.PLATFORM,SysAccountFlowTypeEnum.DOCTOR_SERVICE,platformAmount,exist.getId().toString(),loginUser);

        //订单操作记录处理
        orderInfoLogService.addLog(order.getId(),OrderInfoLogTypeEnum.SETTLEMENT,doctorAmount.toPlainString());

        //订单表操作处理（订单状态、订单更改时间）
        order.setStatus(OrderStatusEnum.SETTLE.getCode());
        order.setUpdateTime(new Date());
        orderInfoService.updateById(order);

        //结算记录表处理（状态，更改人，更改时间）
        exist.setStatus(SettlementStatusEnum.DONE.getCode());
        exist.setUpdateBy(loginUser);
        exist.setUpdateTime(new Date());
        settlementService.updateById(exist);
        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("orderId",order.getId());
            jsonObject.put("money",doctorAmount.toPlainString());
            DySmsHelper.sendSms(doctor.getMobile(),jsonObject, DySmsEnum.SETTLEMENT);
        } catch (Exception e) {
            log.error("发送短信失败",e);
        }
        return Pair.of(true,"结算成功");
    }


    public void confirmOrder(){
        try {
            LocalDateTime yesterday = LocalDateTime.now().minusDays(1);
            LambdaQueryWrapper<OrderInfo> query = Wrappers.lambdaQuery();
            query.eq(OrderInfo::getStatus, OrderStatusEnum.CONFIRM.getCode());
            query.le(OrderInfo::getFinishTime,yesterday);
            List<OrderInfo> orderInfos = orderInfoService.list(query);
            log.info("一共有{}条订单需要变更为待结算",orderInfos.size());
            if (CollectionUtils.isNotEmpty(orderInfos)){
                orderInfos.stream().forEach(item -> {
                    try {
                        this.confirm(item);
                    } catch (Exception e) {
                        log.error("订单变更待结算异常,订单id：{}",item.getId(),e);
                    }
                });
            }
        } catch (Exception e) {
            log.error("订单确认job异常",e);
        }
    }

    @Transactional(rollbackFor = RuntimeException.class)
    public void confirm(OrderInfo item){
        item.setStatus(OrderStatusEnum.SETTLE_ING.getCode());
        item.setUpdateTime(new Date());
        orderInfoService.updateById(item);
        settlementService.initSettlement(item);
        orderInfoLogService.addLog(item.getId(),OrderInfoLogTypeEnum.CONFIRM);
    }
}
